package yunjiao.javatutorials.guava.concurrent.event;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 批量请求处理
 *
 * @author yangyunjiao
 */
public class BatchRequestExample {
    public static void main(String[] args) throws Exception {
        EventProcessor processor = new EventProcessor();

        List<CompletableFuture<String>> futures = new ArrayList<>();

        // 发送多个请求
        for (int i = 1; i <= 5; i++) {
            String requestId = "BATCH-" + i;
            ListenableFuture<String> listenableFuture =
                    processor.sendRequest(requestId, "批量请求 " + i);

            // 将 ListenableFuture 转换为 CompletableFuture
            CompletableFuture<String> completableFuture = new CompletableFuture<>();
            Futures.addCallback(listenableFuture, new FutureCallback<String>() {
                @Override
                public void onSuccess(String result) {
                    completableFuture.complete(result);
                }

                @Override
                public void onFailure(Throwable throwable) {
                    completableFuture.completeExceptionally(throwable);
                }
            }, MoreExecutors.directExecutor());

            futures.add(completableFuture);
        }

        // 模拟批量响应
        new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                try {
                    Thread.sleep(500);
                    String requestId = "BATCH-" + i;
                    if (i == 3) {
                        processor.handleError(requestId, "第三个请求失败");
                    } else {
                        processor.handleResponse(requestId, "批量响应 " + i);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }).start();

        // 等待所有请求完成
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futures.toArray(new CompletableFuture[0])
        );

        allFutures.get(); // 等待所有完成
        System.out.println("所有批量请求处理完成");
        System.out.println("剩余请求数: " + processor.getPendingRequestCount());
    }
}
